راهنمای جامع سفارشیسازی نمایههای عمومی مبتنی بر کلاس جنگو برای توسعه وب قدرتمند و کارآمد. بیاموزید چگونه نماها را مطابق با نیازهای خاص خود تنظیم کنید.
نمایههای مبتنی بر کلاس جنگو: تسلط بر سفارشیسازی نمایههای عمومی
نمایندههای مبتنی بر کلاس جنگو (CBV) راهی قدرتمند و قابل استفاده مجدد برای ساخت برنامههای وب فراهم میکنند. نماهای عمومی، زیرمجموعهای از CBVها، راهحلهای از پیش ساخته شده برای وظایف رایج مانند نمایش لیستها، نماهای جزئیات، ایجاد، بهروزرسانی و حذف اشیاء را ارائه میدهند. در حالی که این نماهای عمومی فوقالعاده راحت هستند، اغلب برای انطباق کامل با نیازهای خاص برنامه شما نیاز به سفارشیسازی دارند. این راهنمای جامع، تکنیکهای مختلفی را برای سفارشیسازی نماهای عمومی جنگو بررسی میکند و شما را قادر میسازد برنامههای وب کارآمد و قابل نگهداری بسازید.
درک نماهای مبتنی بر کلاس جنگو
قبل از پرداختن به سفارشیسازی، اجازه دهید اصول اولیه CBVها و نماهای عمومی را مرور کنیم. نماهای سنتی مبتنی بر تابع (FBV) درخواستهای HTTP را مستقیماً در یک تابع واحد مدیریت میکنند. از سوی دیگر، CBVها منطق نما را به کلاسها سازماندهی میکنند و رویکردی ساختاریافتهتر و شیءگرا ارائه میدهند. این امر منجر به سازماندهی بهتر کد، قابلیت استفاده مجدد و قابلیت آزمایش میشود.
نماهای عمومی، CBVهای از پیش ساخته شدهای هستند که برای مدیریت وظایف رایج توسعه وب طراحی شدهاند. آنها از کلاسهای پایه مانند View
و TemplateView
ارث میبرند و قابلیتهای ویژهای ارائه میدهند. نماهای عمومی رایج عبارتند از:
ListView
: لیستی از اشیاء را نمایش میدهد.DetailView
: جزئیات یک شیء واحد را نمایش میدهد.CreateView
: ایجاد شیء با استفاده از فرم را مدیریت میکند.UpdateView
: بهروزرسانی شیء با استفاده از فرم را مدیریت میکند.DeleteView
: حذف شیء را مدیریت میکند.
این نماهای عمومی یک پایه محکم فراهم میکنند، اما برنامههای دنیای واقعی اغلب نیاز به تنظیم رفتار آنها دارند. بیایید تکنیکهای مختلف سفارشیسازی را بررسی کنیم.
تکنیکهای سفارشیسازی
چندین راه برای سفارشیسازی نماهای عمومی جنگو وجود دارد، از بازنویسی ساده صفات گرفته تا بازنویسی پیچیدهتر متدها. تکنیک مناسب به سطح سفارشیسازی مورد نیاز بستگی دارد.
۱. بازنویسی صفات
سادهترین شکل سفارشیسازی شامل بازنویسی صفات کلاس نمای عمومی است. این برای اصلاح ویژگیهای اساسی مانند مدل، نام الگو یا نام شیء زمینه ایدهآل است.
مثال: سفارشیسازی ListView
فرض کنید میخواهید لیستی از مقالات را نمایش دهید، اما میخواهید از یک الگوی سفارشی و یک نام شیء زمینه متفاوت استفاده کنید.
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles'
def get_queryset(self):
return Article.objects.filter(is_published=True).order_by('-publication_date')
در این مثال، صفات model
، template_name
و context_object_name
را بازنویسی کردهایم. همچنین متد get_queryset
را برای فیلتر کردن مقالات و مرتبسازی آنها بر اساس تاریخ انتشار بازنویسی کردهایم. متد get_queryset
به شما امکان کنترل بر روی اینکه کدام اشیاء در نمای لیست گنجانده میشوند را میدهد. این برای پیادهسازی فیلترینگ، مرتبسازی و صفحهبندی مفید است.
۲. بازنویسی متد
بازنویسی متد به شما امکان میدهد رفتار متدهای موجود در کلاس نمای عمومی را تغییر دهید. این کنترل بیشتری بر منطق نما فراهم میکند. متدهای رایج برای بازنویسی عبارتند از:
get_queryset()
: مجموعه پرسوجو مورد استفاده نما را کنترل میکند.get_context_data()
: دادههایی را به زمینه الگو اضافه میکند.form_valid()
: ارسال موفقیتآمیز فرم را مدیریت میکند.form_invalid()
: ارسال نامعتبر فرم را مدیریت میکند.get_success_url()
: URL را برای هدایت پس از ارسال موفقیتآمیز فرم تعیین میکند.get_object()
: شیء را برای DetailView، UpdateView و DeleteView بازیابی میکند
مثال: سفارشیسازی DetailView
فرض کنید میخواهید جزئیات یک مقاله را نمایش دهید، اما همچنین میخواهید نظرات مرتبط را در زمینه الگو بگنجانید.
from django.views.generic import DetailView
from .models import Article, Comment
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/article_detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comments'] = Comment.objects.filter(article=self.object, is_approved=True)
return context
در اینجا، متد get_context_data()
را برای افزودن یک متغیر comments
به زمینه الگو بازنویسی کردهایم. این به شما امکان میدهد نظرات مرتبط را در الگوی article_detail.html
به راحتی دسترسی یافته و نمایش دهید.
۳. استفاده از Mixin ها
Mixin ها کلاسهای قابل استفاده مجددی هستند که قابلیتهای خاصی را ارائه میدهند. آنها را میتوان با نماهای عمومی ترکیب کرد تا ویژگیهایی را بدون تغییر منطق اصلی نما اضافه کرد. جنگو چندین mixin داخلی ارائه میدهد و شما میتوانید mixin های خود را نیز ایجاد کنید.
مثال: استفاده از LoginRequiredMixin
LoginRequiredMixin
تضمین میکند که فقط کاربران وارد شده میتوانند به یک نمای خاص دسترسی داشته باشند.
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # آدرس URL موفقیت مورد نظر خود را جایگزین کنید
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
در این مثال، از LoginRequiredMixin
برای محدود کردن دسترسی به ArticleCreateView
برای کاربران وارد شده استفاده کردهایم. همچنین متد form_valid
را برای تنظیم خودکار نویسنده مقاله به کاربر فعلی بازنویسی کردهایم. این نشان میدهد که چگونه mixin ها را میتوان با بازنویسی متد ترکیب کرد تا سفارشیسازی پیچیده حاصل شود.
ایجاد Mixin های سفارشی
شما همچنین میتوانید mixin های خود را برای بستهبندی منطق قابل استفاده مجدد ایجاد کنید. به عنوان مثال، ممکن است mixini را ایجاد کنید که به طور خودکار کاربر فعلی را به عنوان نویسنده یک نمونه مدل تنظیم کند، یا mixini که بررسی مجوزها را مدیریت کند.
from django.contrib.auth.mixins import UserPassesTestMixin
class AuthorRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_staff or (self.request.user == self.get_object().author)
def handle_no_permission(self):
# جایگزین با هدایت یا مدیریت خطای مورد نظر خود
return redirect('permission_denied') # یا یک استثنا ایجاد کنید
این AuthorRequiredMixin
فقط به اعضای کارکنان یا نویسنده شیء اجازه دسترسی میدهد. شما میتوانید از این mixin با UpdateView
یا DeleteView
استفاده کنید تا اطمینان حاصل کنید که فقط کاربران مجاز میتوانند اشیاء را تغییر دهند یا حذف کنند.
۴. سفارشیسازی الگو
در حالی که تکنیکهای بالا بر تغییر منطق نما تمرکز دارند، سفارشیسازی الگو برای کنترل نمایش دادهها ضروری است. نماهای عمومی از الگوها برای رندر کردن خروجی HTML استفاده میکنند. شما میتوانید این الگوها را برای مطابقت با طراحی و برند برنامه خود سفارشی کنید.
قراردادهای نامگذاری الگو
نماهای عمومی از قراردادهای نامگذاری الگوی خاصی پیروی میکنند. به عنوان مثال:
ListView
:<app_name>/<model_name>_list.html
(مثلاًarticles/article_list.html
)DetailView
:<app_name>/<model_name>_detail.html
(مثلاًarticles/article_detail.html
)CreateView
/UpdateView
:<app_name>/<model_name>_form.html
(مثلاًarticles/article_form.html
)DeleteView
:<app_name>/<model_name>_confirm_delete.html
(مثلاًarticles/article_confirm_delete.html
)
شما میتوانید صفت template_name
را در کلاس نما بازنویسی کنید تا از یک الگوی متفاوت استفاده کنید. در داخل الگو، میتوانید از طریق شیء زمینه به دادههای ارائه شده توسط نما دسترسی پیدا کنید. نام شیء زمینه پیشفرض معمولاً نسخه کوچک شده نام مدل است (مثلاً article
برای Article
). شما میتوانید این را با استفاده از صفت context_object_name
تغییر دهید.
مثال: سفارشیسازی الگوی ListView
در الگوی articles/article_list.html
، میتوانید روی متغیر زمینه articles
(همانطور که در مثال ArticleListView
در بالا تعریف شده است) تکرار کنید تا لیست مقالات را نمایش دهید.
<h1>مقالات</h1>
<ul>
{% for article in articles %}
<li><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></li>
{% endfor %}
</ul>
۵. سفارشیسازی فرم (CreateView & UpdateView)
CreateView
و UpdateView
برای مدیریت ورودی کاربر به فرمهای جنگو متکی هستند. سفارشیسازی این فرمها به شما امکان میدهد فیلدهای نمایش داده شده، قوانین اعتبارسنجی آنها و ظاهر آنها را کنترل کنید.
استفاده از form_class
شما میتوانید کلاس فرم مورد استفاده را با صفت form_class
در کلاس نما مشخص کنید. اگر کلاس فرمی را مشخص نکنید، جنگو به طور خودکار یک ModelForm
را بر اساس مدل مرتبط با نما ایجاد میکند.
بازنویسی متدهای فرم
شما میتوانید متدهایی را در کلاس فرم خود بازنویسی کنید تا رفتار آن را سفارشی کنید. متدهای رایج برای بازنویسی عبارتند از:
__init__()
: فرم را مقداردهی اولیه کرده و فیلدهای آن را تغییر دهید.clean()
: اعتبارسنجی سفارشی را در چندین فیلد انجام دهید.clean_<field_name>()
: اعتبارسنجی سفارشی را برای یک فیلد خاص انجام دهید.
مثال: سفارشیسازی فرم مقاله
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['content'].widget = forms.Textarea(attrs={'rows': 5})
def clean_title(self):
title = self.cleaned_data['title']
if len(title) < 5:
raise forms.ValidationError("عنوان باید حداقل ۵ کاراکتر باشد.")
return title
در این مثال، ArticleForm
را با تنظیم صفت fields
در کلاس Meta
برای مشخص کردن اینکه کدام فیلدها باید در فرم گنجانده شوند، سفارشی کردهایم. همچنین متد __init__()
را برای سفارشیسازی ویجت فیلد content
و متد clean_title()
برای افزودن اعتبارسنجی سفارشی برای فیلد title
بازنویسی کردهایم.
۶. مدیریت پویا فرم
گاهی اوقات نیاز دارید که فرم را به صورت پویا بر اساس کاربر یا عوامل دیگر تنظیم کنید. شما میتوانید این کار را با بازنویسی متد get_form_kwargs()
در کلاس نما انجام دهید. این متد به شما امکان میدهد آرگومانهای کلیدواژهای اضافی را به سازنده فرم ارسال کنید.
مثال: ارسال کاربر به فرم
from django.views.generic import CreateView
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # آدرس URL موفقیت مورد نظر خود را جایگزین کنید
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
سپس، در ArticleForm
خود، میتوانید از طریق آرگومان کلیدواژهای user
در متد __init__()
به کاربر دسترسی پیدا کنید.
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if self.user and not self.user.is_staff:
del self.fields['is_published'] # فقط کارکنان میتوانند منتشر کنند
در این مثال، ما کاربر فعلی را به فرم ارسال میکنیم و به طور پویا فیلد is_published
را حذف میکنیم اگر کاربر عضو کارکنان نباشد. این نشان میدهد که چگونه میتوانید فرم را به صورت پویا بر اساس مجوزهای کاربر تنظیم کنید.
سفارشیسازی پیشرفته: استفاده از ViewSet ها
برای برنامههای پیچیدهتر، به ویژه آنهایی که شامل API ها هستند، استفاده از ViewSet های Django REST Framework (DRF) را در نظر بگیرید. ViewSet ها نماهای مرتبط (مانند لیست، ایجاد، بازیابی، بهروزرسانی، حذف) را در یک کلاس واحد ترکیب میکنند و راهی تمیزتر و سازمانیافتهتر برای مدیریت نقاط پایانی API ارائه میدهند.
مثال: ایجاد ArticleViewSet
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
این ArticleViewSet
ساده تمام عملیات استاندارد CRUD (ایجاد، خواندن، بهروزرسانی، حذف) را برای مقالات فراهم میکند. شما میتوانید ViewSet ها را با استفاده از تکنیکهای مشابه نماهای عمومی سفارشی کنید، مانند بازنویسی متدهایی مانند get_queryset()
، perform_create()
و perform_update()
.
ملاحظات سراسری برای سفارشیسازی نمای عمومی
هنگام سفارشیسازی نماهای عمومی برای مخاطبان جهانی، ملاحظات زیر را در نظر داشته باشید:
- بومیسازی و بینالمللیسازی (L10n/I18n): اطمینان حاصل کنید که الگوها و فرمهای شما از چندین زبان و قالبهای منطقهای پشتیبانی میکنند. از ویژگیهای داخلی i18n/l10n جنگو استفاده کنید.
- مناطق زمانی: تبدیلهای منطقه زمانی را به درستی مدیریت کنید تا تاریخها و زمانها را به زمان محلی کاربر نمایش دهید. از ماژول
timezone
جنگو استفاده کنید. - قالببندی ارز: مقادیر ارز را به طور مناسب برای مناطق مختلف قالببندی کنید. برای قالببندی ارز، استفاده از کتابخانهای مانند
babel
را در نظر بگیرید. - قالببندی تاریخ و عدد: از قالبهای تاریخ و عدد مناسب بر اساس منطقه کاربر استفاده کنید.
- دسترسیپذیری: اطمینان حاصل کنید که نماها و الگوهای سفارشی شما برای کاربران دارای معلولیت قابل دسترسی هستند. از دستورالعملهای دسترسیپذیری مانند WCAG پیروی کنید.
- طراحی واکنشگرا: اطمینان حاصل کنید که الگوهای شما واکنشگرا هستند و با اندازههای مختلف صفحه و دستگاههای مورد استفاده کاربران در سراسر جهان سازگار میشوند.
- حساسیت فرهنگی: هنگام طراحی نماها و الگوهای خود، به تفاوتهای فرهنگی توجه داشته باشید. از تصاویر یا زبانی که ممکن است برای فرهنگهای خاص توهینآمیز باشد، اجتناب کنید. به عنوان مثال، ارتباط رنگها و نمادها میتواند معانی بسیار متفاوتی در فرهنگهای مختلف داشته باشد.
مثال: مدیریت مناطق زمانی
برای نمایش تاریخ انتشار در منطقه زمانی محلی کاربر، میتوانید از تگ timezone
در الگوی خود استفاده کنید:
{% load tz %}
<p>منتشر شده در: {% timezone article.publication_date %}</p>
اطمینان حاصل کنید که USE_TZ = True
را در فایل تنظیمات جنگو خود تنظیم کردهاید.
بهترین شیوهها برای سفارشیسازی نمای عمومی
این بهترین شیوهها را برای اطمینان از قابل نگهداری و کارآمد بودن سفارشیسازیهای خود دنبال کنید:
- ساده نگه دارید: از پیچیدهکردن بیش از حد سفارشیسازیهای خود اجتناب کنید. از سادهترین تکنیکی که نتیجه مورد نظر را به دست میآورد استفاده کنید.
- کد خود را مستند کنید: برای توضیح سفارشیسازیها و دلیل ضرورت آنها، نظرات را اضافه کنید.
- به طور کامل آزمایش کنید: برای اطمینان از اینکه سفارشیسازیهای شما به درستی کار میکنند، تستهای واحد بنویسید.
- از Mixin ها عاقلانه استفاده کنید: Mixin های قابل استفاده مجدد برای بستهبندی قابلیتهای رایج ایجاد کنید.
- قراردادهای جنگو را دنبال کنید: به سبک کدنویسی و قراردادهای نامگذاری جنگو پایبند باشید.
- امنیت را در نظر بگیرید: هنگام سفارشیسازی نماها، از آسیبپذیریهای امنیتی احتمالی آگاه باشید. ورودی کاربر را پاکسازی کنید و از حملات رایج مانند Cross-Site Scripting (XSS) و SQL Injection محافظت کنید.
نتیجهگیری
نماهای عمومی مبتنی بر کلاس جنگو راهی قدرتمند و انعطافپذیر برای ساخت برنامههای وب ارائه میدهند. با تسلط بر تکنیکهای سفارشیسازی که در این راهنما شرح داده شده است، میتوانید نماهای عمومی را مطابق با نیازهای خاص خود تنظیم کنید و برنامههای وب کارآمد، قابل نگهداری و قابل دسترسی جهانی ایجاد کنید. از بازنویسی ساده صفات گرفته تا بازنویسی پیچیده متدها و استفاده از mixin ها، امکانات گسترده هستند. به یاد داشته باشید که دیدگاههای جهانی و بهترین شیوهها را برای اطمینان از اینکه برنامههای شما به مخاطبان بینالمللی متنوعی خدمات ارائه میدهند، در نظر بگیرید.